package chat

import (
	"encoding/json"
	"fmt"
	"github.com/gorilla/websocket"
	"log"
	"net/http"
	"strings"
	"time"
	"wave-service/server/app/validate"
)

type Client struct {
	hub  *Hub
	conn *websocket.Conn
	send chan []byte
	Id   string
}

var clients map[string]*Client

var upGrader = websocket.Upgrader{
	ReadBufferSize:  1024,
	WriteBufferSize: 1024,
	CheckOrigin: func(r *http.Request) bool {
		return true
	},
}

func (c *Client) WriteMsg() {
	defer func() {
		_ = c.conn.Close()
	}()
	for {
		select {
		case message, ok := <-c.send:
			if !ok {
				c.conn.WriteMessage(websocket.CloseMessage, []byte{}) // 错误 关闭 channel
				msgStore.ErrorLogServer(fmt.Errorf("系统错误：未知"))
				return
			}
			w, err := c.conn.NextWriter(websocket.TextMessage)
			if err != nil {
				return
			}
			_, _ = w.Write(message)
			n := len(c.send)
			for i := 0; i < n; i++ {
				_, _ = w.Write(<-c.send)
			}
			if err := w.Close(); err != nil {
				return
			}
		}
	}
}

func (c *Client) ReadMsg() {
	defer func() {
		c.hub.unregister <- c
		_ = c.conn.Close()
	}()
	for {
		_, strByte, err := c.conn.ReadMessage()
		if err != nil {
			if websocket.IsUnexpectedCloseError(err, websocket.CloseGoingAway, websocket.CloseAbnormalClosure) {
				msgStore.ErrorLogServer(fmt.Errorf("系统错误：%v", err))
			}
			break
		}
		//log.Println("clients", clients)
		if clients[c.Id] != c {
			msgStore.ErrorLogServer(fmt.Errorf("用户`%v`未登录，不能发送消息", c.Id))
			continue
		}
		message := Message{}
		err = json.Unmarshal(strByte, &message)
		//log.Println("ReadMsg：", message.String())
		// 验证消息
		errStr := validate.Verify(message)
		if errStr != "" {
			msgStore.ErrorLogServer(fmt.Errorf("用户`%v`发送的消息有错误 %v", c.Id, errStr))
			continue
		}
		if message.Cmd == CMD_MSG {
			// 过滤特殊字符
			message.Content = TrimHtml(message.Content)
			message.ToUserUuid = TrimHtml(message.ToUserUuid)
			message.ToUserUuid = strings.TrimSpace(message.ToUserUuid)

			message.SendTime = time.Now().Format("2006-01-02 15:04:05")
			message.UserUuid = c.Id

			if message.Content == "" {
				msgStore.ErrorLogServer(fmt.Errorf("用户`%v`发送的消息内容为空", c.Id))
				continue
			}

			if message.ToUserUuid == "" {
				if _, ok := clients[message.ToUserUuid]; !ok {
					log.Println("接收消息跳过")
					continue
				}
			}
			if string(strByte) != "" {
				if msgStore != nil {
					msgStore.SendMessage(message)
				}
				c.hub.broadcast <- message // 转发读取到的channel消息
			}
		} else if message.Cmd == CMD_HEART {
			// 心跳
			heartMsg := Message{
				Cmd:        CMD_HEART,
				UserUuid:   c.Id,
				ToUserUuid: c.Id,
				Type:       1,
				Content:    "ping",
			}
			c.hub.broadcast <- heartMsg
		}

	}
}
